package ee.siimoliver.chat.GUI;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.LinkedList;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;

import net.miginfocom.swing.MigLayout;
import ee.siimoliver.chat.GUI.dialogs.NewChatDialog;
import ee.siimoliver.chat.controllers.ChatOutputController;
import ee.siimoliver.chat.controllers.ChatSessionController;
import ee.siimoliver.chat.server.ChatMate;
import ee.siimoliver.chat.utils.ChatUtils;
import ee.siimoliver.chat.utils.Const;

public class ChatContentPanel extends JPanel implements ChatOutputController {

	private static final long serialVersionUID = 1L;
	private JSplitPane splitPane;
	private JButton btnSend;
	private JButton btnAdd;
	private JTextArea inputArea;
	private JTextArea chatArea;
	private JPanel chattablesPanel;
	private LinkedList<JLabel> lblChattingNames;
	private ChatSessionController chatSessionController;
	private JFrame parent;
	
	public ChatContentPanel(JFrame parent, ChatSessionController chatSessionController) {
		this.chatSessionController = chatSessionController;
		this.parent = parent;
		initFields();
		addProperties();
	}
	
	private void addProperties() {
		btnSend.addActionListener(new SendAction());
		btnAdd.addActionListener(new AddAction());
		splitPane.setResizeWeight(1);
		inputArea.setFont(Const.INPUTAREA_FONT);
		chatArea.setFont(Const.CHATAREA_FONT);
		ChatUtils.mapInputActionToEnter(inputArea, btnSend);
		inputArea.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK), "shift enter");
		inputArea.getActionMap().put("shift enter", new AbstractAction() {
			private static final long serialVersionUID = 1L;
			@Override
			public void actionPerformed(ActionEvent ae) {
				inputArea.append("\n");
			}
		});
	}
	
	private void initFields() {
		setLayout(new BorderLayout());
		lblChattingNames = new LinkedList<JLabel>();
		chattablesPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
		chatArea = new JTextArea();
		inputArea = new JTextArea();
		btnSend = new JButton(Const.LBL_SEND);
		btnAdd = new JButton(Const.ICON_ADD);
		splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createMessageArea(), createInputArea());
		add(splitPane);
	}
	
	private JPanel createMessageArea() {
		JPanel messageAreaPane = new JPanel(new BorderLayout());
		updatePanel();
		messageAreaPane.add(chattablesPanel, BorderLayout.NORTH);
		chatArea.setEditable(false);
		messageAreaPane.add(new JScrollPane(chatArea), BorderLayout.CENTER);
		return messageAreaPane;
	}
	
	private JPanel createInputArea() {
		JPanel inputPanel = new JPanel(new MigLayout("", "[grow, fill][fill]", "[grow, fill]"));
		inputPanel.add(new JScrollPane(inputArea), "cell 0 0, span 1 2");
		inputPanel.add(btnSend, "height 60!, cell 1 0");
		inputPanel.add(btnAdd, "height 60!, cell 1 1");
		return inputPanel;
	}
	
	@Override
	public void updatePanel() {
		lblChattingNames.clear();
		lblChattingNames.add(new JLabel(Const.LBL_CHATTING));
		if (chatSessionController != null) {
			int i = 0;
			int end = chatSessionController.getChatmates().size() - 1;
			String addon = ",";
			for (ChatMate chatmate : chatSessionController.getChatmates()) {
				if (i == end) {
					addon = "";
				}
				lblChattingNames.add(new JLabel(chatmate.getName() + chatmate.getInfo() + addon));
				i++;
			}
		}
		chattablesPanel.removeAll();
		for (JLabel label : lblChattingNames) {
			chattablesPanel.add(label);
		}
		validate();
		repaint();
	}
	
	@Override
	public void resetPanel() {
		inputArea.setText("");
		chatArea.setText("");
		updatePanel();
	}
	
	public void attachBusinessLogicController(ChatSessionController controller) {
		this.chatSessionController = controller;
		updatePanel();
	}
	
	public ChatSessionController getChatSessionController() {
		return this.chatSessionController;
	}
	
	private class SendAction implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (chatSessionController != null) {
				try {
					chatSessionController.sendAction(inputArea.getText());
				} catch (IOException e1) {
					JOptionPane.showMessageDialog(parent, e1.getMessage(), Const.TXT_ERROR, JOptionPane.ERROR_MESSAGE);
				}
				inputArea.setText("");
				updatePanel();
			}
		}
	}
	private class AddAction implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			NewChatDialog ncd = new NewChatDialog(parent, 
					((ChatFrame) parent).getBusinessLogicController(), 
					Const.LBL_ADD, chatSessionController);
			ncd.display();
		}
	}
	@Override
	public void clearText() {
		chatArea.setText("");
	}

	@Override
	public void appendText(String text, String from) {
		chatArea.append(String.format(Const.CHAT_OUPUT_FORMAT, from, text));
		validate();
		repaint();
	}
}
